package ca.polymtl.rubikcube.CubeActivity.model;

import ca.polymtl.rubikcube.CubeActivity.model.Side;
import ca.polymtl.rubikcube.util.Color;

public class Face {
	final Rubik rubik;
	final Side side;

	public Face(Rubik rubik, Side side) {
		this.rubik = rubik;
		this.side = side;

	}

	public void assignAll(Color c) {
		for (int j = 0; j < 3; j++) {
			for (int i = 0; i < 3; i++) {
				assign(i, j, c);
			}
		}
	}

	public void assign(int x, int y, Color c) {
		switch (side) {
		case FRONT:
			rubik.cubeletAt(x, 2 - y, 2).setSideColor(this.side, c);
			break;
		case UP:
			rubik.cubeletAt(x, 2, y).setSideColor(this.side, c);
			break;
		case RIGHT:
			rubik.cubeletAt(2, 2 - x, y).setSideColor(this.side, c);
			break;
		case BACK:
			rubik.cubeletAt(y, 2 - x, 0).setSideColor(this.side, c);
			break;
		case DOWN:
			rubik.cubeletAt(y, 0, x).setSideColor(this.side, c);
			break;
		case LEFT:
			rubik.cubeletAt(0, 2 - y, x).setSideColor(this.side, c);
			break;
		}
	}

	public Color colorAt(int x, int y) {
		switch (side) {
		case FRONT:
			return rubik.cubeletAt(x, 2 - y, 2).getSideColor(this.side);
		case UP:
			return rubik.cubeletAt(x, 2, y).getSideColor(this.side);
		case RIGHT:
			return rubik.cubeletAt(2, 2 - x, y).getSideColor(this.side);
		case BACK:
			return rubik.cubeletAt(y, 2 - x, 0).getSideColor(this.side);
		case DOWN:
			return rubik.cubeletAt(y, 0, x).getSideColor(this.side);
		case LEFT:
			return rubik.cubeletAt(0, 2 - y, x).getSideColor(this.side);
		default:
			return null;
		}
	}

	public Color[][] getColors() {
		Color[][] colors = new Color[3][3];

		for (int j = 0; j < 3; j++) {
			for (int i = 0; i < 3; i++) {
				colors[i][j] = colorAt(i, j);
			}
		}

		return colors;
	}
	
	public static Color[][] rotateLeft(Color[][] colorsIn) {
		Color[][] colorsOut = new Color[3][3];
		
		colorsOut[0][0] = colorsIn[2][0];
		colorsOut[0][1] = colorsIn[1][0];
		colorsOut[0][2] = colorsIn[0][0];
		colorsOut[1][0] = colorsIn[2][1];
		colorsOut[1][1] = colorsIn[1][1];
		colorsOut[1][2] = colorsIn[0][1];
		colorsOut[2][0] = colorsIn[2][2];
		colorsOut[2][1] = colorsIn[1][2];
		colorsOut[2][2] = colorsIn[0][2];
		
		return colorsOut;
	}
	
	public static Color[][] rotateRight(Color[][] colorsIn) {
		Color[][] colorsOut = new Color[3][3];
		
		colorsOut[0][0] = colorsIn[0][2];
		colorsOut[0][1] = colorsIn[1][2];
		colorsOut[0][2] = colorsIn[2][2];
		colorsOut[1][0] = colorsIn[0][1];
		colorsOut[1][1] = colorsIn[1][1];
		colorsOut[1][2] = colorsIn[2][1];
		colorsOut[2][0] = colorsIn[0][0];
		colorsOut[2][1] = colorsIn[1][0];
		colorsOut[2][2] = colorsIn[2][0];
		
		return colorsOut;
	}

}
